﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Web.Security;
using RhotCMS.AdditionalCode;
using Utils;
using RhotCMS.Controllers;
using Core.AdditionalInterfaces;

namespace RhotCMS.Filters
{
	public class PreviewAttribute : ActionFilterAttribute
	{
		string _url;

		public override void OnActionExecuting(ActionExecutingContext filterContext)
		{
            var controllerObject = filterContext.Controller;

            if (!ClassHelpers.IsTypeHasParentType<IAllowPreview>(controllerObject.GetType()))
                return;                

			_url = filterContext.HttpContext.Request.Url.AbsoluteUri;
			bool preview = false;
			if (_url.Contains("preview"))
			{
				//Проверка на авторизацию
				if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
					FormsAuthentication.RedirectToLoginPage();

				preview = true;
			}

            RhotCMSController controller = controllerObject as RhotCMSController;
            if(controller!=null)
            controller.IsPreview = preview;

			base.OnActionExecuting(filterContext);
		}

		public override void OnResultExecuting(ResultExecutingContext filterContext)
		{
            var controllerObject = filterContext.Controller;

            if (!ClassHelpers.IsTypeHasParentType<IAllowPreview>(controllerObject.GetType()))
                return; 

            if (_url.Contains("preview") && !_url.Contains(String.Format("{0}Administration", URLUtils.GetAbsVirtualAppPath())))
			{
				HttpResponseBase response = filterContext.HttpContext.Response;
				response.Filter = new PreviewFilter(response.Filter);
			}
		}       

		public class PreviewFilter : Stream
		{
			private Stream _stream;
			private Func<string, string> _filter;
			public string Html { get; set; }


			public PreviewFilter(Stream stream)
			{
				_stream = stream;
                LinksHrefRewriter hrewriter = new LinksHrefRewriter();
				_filter = s => hrewriter.AddPreview(s);
			}


			//overridden functions omitted for clarity.

			public override void Write(byte[] buffer, int offset, int count)
			{
				// capture the data and convert to string 

				byte[] data = new byte[count];
				Buffer.BlockCopy(buffer, offset, data, 0, count);

				string s = Encoding.Default.GetString(buffer, 0, count);

				Html += s;

				if (Html.Contains("<html>") && Html.Contains("</html>"))
				{
					// filter the string					
					Html = _filter(Html);
					// write the data to stream 
					byte[] outdata = Encoding.Default.GetBytes(Html);
					_stream.Write(outdata, 0, outdata.GetLength(0));
				}
			}


			public override bool CanRead
			{
				get { throw new NotImplementedException(); }
			}

			public override bool CanSeek
			{
				get { throw new NotImplementedException(); }
			}

			public override bool CanWrite
			{
				get { return true; }
			}

			public override void Close()
			{
				_stream.Close();
			}

			public override void Flush()
			{
				//throw new NotImplementedException();
			}

			public override long Length
			{
				get { throw new NotImplementedException(); }
			}

			public override long Position
			{
				get
				{
					throw new NotImplementedException();
				}
				set
				{
					throw new NotImplementedException();
				}
			}

			public override int Read(byte[] buffer, int offset, int count)
			{
				throw new NotImplementedException();
			}

			public override long Seek(long offset, SeekOrigin origin)
			{
				throw new NotImplementedException();
			}

			public override void SetLength(long value)
			{
				throw new NotImplementedException();
			}
		}

	}
}
